package com.shuai.baibi.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shuai.baibi.common.BaseResponse;
import com.shuai.baibi.common.ErrorCode;
import com.shuai.baibi.constant.UserConstant;
import com.shuai.baibi.exception.BusinessException;
import com.shuai.baibi.model.dto.user.UserLoginRequest;
import com.shuai.baibi.model.dto.user.UserRegisterRequest;
import com.shuai.baibi.model.entity.User;
import com.shuai.baibi.model.vo.UserVO;
import com.shuai.baibi.service.UserService;
import com.shuai.baibi.utils.PasswordUtil;
import com.shuai.baibi.utils.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;
    private final Object lock = new Object();    // 加锁对象

    @PostMapping("/register")
    public BaseResponse<UserVO> register(@RequestBody UserRegisterRequest userRegisterRequest) {
        if (userRegisterRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String userAccount = userRegisterRequest.getUserAccount();
        String checkPassword = userRegisterRequest.getCheckPassword();
        String userPassword = userRegisterRequest.getUserPassword();
        if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 检验输入密码和校验密码是否一致
        if (!StringUtils.equals(userPassword, checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码和校验密码不一致！");
        }
        // 对用户输入的密码进行加密
        User user = new User();
        String encryptedPwd = PasswordUtil.encryptPwd(userPassword);
        BeanUtils.copyProperties(userRegisterRequest, user);
        user.setUserPassword(encryptedPwd);
        // 保存注册用户
        synchronized (lock) {
            // 校验数据库中是否已经有该用户名
            LambdaQueryWrapper<User> userQueryWrapper = new LambdaQueryWrapper<>();
            userQueryWrapper.eq(User::getUserAccount, userAccount);
            if (userService.count(userQueryWrapper) > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名已存在");
            }
            // 保存用户
            userService.save(user);
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return ResultUtils.success(userVO);
    }


    @PostMapping("/login")
    public BaseResponse<UserVO> login(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
        if (userLoginRequest == null
                || StringUtils.isAllBlank(userLoginRequest.getUserAccount(), userLoginRequest.getUserPassword())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 根据用户名从数据库中查询用户信息
        LambdaQueryWrapper<User> userQueryWrapper = new LambdaQueryWrapper<>();
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();
        userQueryWrapper.eq(User::getUserAccount, userAccount);
        User user = userService.getOne(userQueryWrapper);
        if (user == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在！");
        }
        if (!PasswordUtil.check(user.getUserPassword(), userPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名或密码错误！");
        }
        // 返回登录成功信息
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        // 存储用户会话对象
        request.getSession().setAttribute(UserConstant.LOGIN_STATE_KEY, userVO);
        return ResultUtils.success(userVO);
    }


    @GetMapping("/login_info")
    public BaseResponse<UserVO> getLoginUserInfo(HttpServletRequest request) {
        HttpSession session = request.getSession(true);
        UserVO userVO;
        if (session == null || (userVO = (UserVO) session.getAttribute(UserConstant.LOGIN_STATE_KEY)) == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        return ResultUtils.success(userVO);
    }
}
